library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity mixcol is
    Port ( datain : in  STD_LOGIC_VECTOR (31 downto 0);
           dataout : out  STD_LOGIC_VECTOR (31 downto 0);
			  clk : in STD_LOGIC);
end mixcol;

architecture Structural of mixcol is
	alias s3c : std_logic_vector(7 downto 0) is datain(7 downto 0);
	alias s2c : std_logic_vector(7 downto 0) is datain(15 downto 8);
	alias s1c : std_logic_vector(7 downto 0) is datain(23 downto 16);
	alias s0c : std_logic_vector(7 downto 0) is datain(31 downto 24);
	
	alias o_s3c : std_logic_vector(7 downto 0) is dataout(7 downto 0);
	alias o_s2c : std_logic_vector(7 downto 0) is dataout(15 downto 8);
	alias o_s1c : std_logic_vector(7 downto 0) is dataout(23 downto 16);
	alias o_s0c : std_logic_vector(7 downto 0) is dataout(31 downto 24);
	
	signal s0c_x2, s0c_x3, s1c_x2, s1c_x3, s2c_x2, s2c_x3, s3c_x2, s3c_x3 : std_logic_vector(7 downto 0);
begin
	-- Obliczanie s0, s1c, s2c i s3c przemnozonych przez 02 i 03
	mul2_0: entity work.mul(Behavioral)
		port map (datain => s0c,	multiplier => "10", dataout => s0c_x2);
	mul2_1: entity work.mul(Behavioral)
		port map (datain => s1c, multiplier => "11", dataout => s1c_x3);
	mul2_2: entity work.mul(Behavioral)
		port map (datain => s1c, multiplier => "10", dataout => s1c_x2);
	mul2_3: entity work.mul(Behavioral)
		port map (datain => s2c, multiplier => "11", dataout => s2c_x3);
	mul2_4: entity work.mul(Behavioral)
		port map (datain => s2c, multiplier => "10", dataout => s2c_x2);
	mul2_5: entity work.mul(Behavioral)
		port map (datain => s3c, multiplier => "11", dataout => s3c_x3);
	mul2_6: entity work.mul(Behavioral)
		port map (datain => s0c, multiplier => "11", dataout => s0c_x3);
	mul2_7: entity work.mul(Behavioral)
		port map (datain => s3c, multiplier => "10", dataout => s3c_x2);

process (clk)
begin
	if (rising_edge(clk)) then
		-- Obliczanie wedlug wzoru 5.6 z FIPS-197 (s. 18)
		o_s0c <= s0c_x2 xor s1c_x3 xor s2c xor s3c;
		o_s1c <= s0c xor s1c_x2 xor s2c_x3 xor s3c;
		o_s2c <= s0c xor s1c xor s2c_x2 xor s3c_x3;
		o_s3c <= s0c_x3 xor s1c xor s2c xor s3c_x2;
	end if;
end process;

end Structural;
